<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
<script>
	// 首先我们来定义三个构造器函数
	function Shape() {
		this.name = 'shape';
		this.toString = function() {
			return this.name;
		}
	}

	function TwoDShape() {
		this.name = '2D shape';
	}

	function Triangle(side, height) {
		this.name = 'Triangle';
		this.side = side;
		this.height = height;
		this.getArea = function () {
			return this.side * this.height / 2;
		}
	}

	TwoDShape.prototype = new Shape();
	Triangle.prototype = new TwoDShape();

	// 在这里，我们将对象直接创建在TwoDShape对象的prototype属性中，并没有去扩展这些对象的原有属性。也就是说，我们用构造器Shape()（通过new操作符）另建了一个新的对象，然后它去覆盖TwoDShape构造器的prototype属性。Triangle对象也是一样的，他的prototype属性是由构造器TwoDShape()负责创建的（通过new操作符）。切记：JavaScript是一种完全依靠对象的语言，其中没有类的概念。因此我们需要直接用new Shape()构造一个实体，然后才能通过该实体的属性完成相关的继承工作，而不能直接继承Shape()构造器。另外这也确保了在继承实现之后，我们对Shape()所进行的任何修改、重写甚至删除，都不会对TwoDShape()产生影响，因为我们所继承的只是由该构造器所创建的一个实体

	// 当我们对对象的prototype属性进行完全替换时（这不同于向prototype指向的对象添加属性），有可能会对对象的constructor属性产生一定的副作用。所以，在我们完成相关的继承关系设定后，对这些对象的constructor属性进行相应的重置是一个非常好的习惯
	TwoDShape.prototype.constructor = TwoDShape;
	Triangle.prototype.constructor = Triangle;

	// 下面，我们来测试一下目前为止所实现的内容，先创建一个Triangle对象，然后调用他的getArea()方法
	var my = new Triangle(5, 10);
	console.log(my.getArea());

	// 尽管my对象中并没有属于自己的toString()方法，但我们依然可以调用它所继承的toString()方法。需要注意的是，虽然我们这里调用的是一个继承方法，但this所指向的依然是my对象
	console.log(my.toString());

	// 如果我们向my对象询问你的构造器函数是哪一个，他应该是能够给出正确的答案的，因为我们在构建继承关系时已经对相关的constructor属性进行了重置
	console.log(my.constructor === Triangle);
	console.log(my instanceof Shape);
	console.log(my instanceof TwoDShape);
	console.log(my instanceof Triangle);
	console.log(my instanceof Array);

	// 同样的，当我们以my参数调用这些构造器函数原型的isPropertypeOf()方法时，结果也是如此
	console.log(Shape.prototype.isPrototypeOf(my));
	console.log(TwoDShape.prototype.isPrototypeOf(my));
	console.log(Triangle.prototype.isPrototypeOf(my));
	console.log(String.prototype.isPrototypeOf(my));

	// 我们也可以用其他两个构造器来创建对象，用new TwoDShape()所创建的对象也可以获得继承自Shape()的toString()方法
	var td = new TwoDShape();
	console.log(td.constructor === TwoDShape);
	console.log(td.toString());

	var s = new Shape();
	console.log(s.constructor === Shape);
</script>
</body>
</html>